//
// Created by funstep on 1/28/20.
//

#include <csignal>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include "memory"
#include "restbed"
using namespace restbed;

int main(){
    auto service = std::make_shared<Service>();
    auto settings = std::make_shared<Settings>();
    try {

        service->set_ready_handler([&](Service &) {
            //web_api::debug_logger->info("web api service at [{0}:{1}] is ready!", this->this_ip, this->port);
            //service_ready.set_value(true);
        });
        service->set_error_handler([&](const int error, const std::exception &e, const std::shared_ptr<Session> &session) {
            //web_api::debug_logger->info("api service has error with code {0} and exception {1}", error, e.what());
        });
        settings->set_bind_address("127.0.0.1");
        settings->set_port(8080);
        // settings->set_default_header("Connection", "close");
        settings->set_worker_limit(1);
        settings->set_connection_limit(100);

        service->set_signal_handler(SIGTERM, [&](const int signal_number){
            int k=0;
        });

        service->set_signal_handler(SIGINT, [&](const int signal_number){
            int k = 0;
        });
        //service->set_signal_handler()

        service->schedule([](){
            auto cmd = boost::filesystem::read_symlink(boost::filesystem::path("/proc/self/exe"));
            std::cout << cmd << std::endl;
            //this->logger->info("---------------------------------------------------------------------------");
            auto str_cmd = cmd.string();
            if (boost::icontains(str_cmd, "deleted")) {
                boost::erase_all(str_cmd, "deleted");
                boost::erase_all(str_cmd, "(");
                boost::erase_all(str_cmd, ")");
                boost::trim(str_cmd);

            }
            char *cmd_char = const_cast<char *>(str_cmd.c_str());
            char *argv_send[2];
            argv_send[0] = cmd_char;
            argv_send[1] = NULL;
            std::cout << "\n\n" << std::endl;
            auto rt = execv(cmd_char, argv_send);

        }, std::chrono::seconds(5));

    } catch (...) {
        int k=0;
        //web_api::logger->error("an error when set the api services.");
    }

    while (true) {
        try {
            std::cout << "start" << std::endl;
            service->start(settings);
        } catch (std::exception &e) {
            uint64_t time = 1000;
            std::cout << e.what() << std::endl;
            //web_api::debug_logger->error("set service with error {0} at [{2}:{3}]. wait {1} ms to retry.", e.what(), time, this->this_ip, this->port);
            std::this_thread::sleep_for(std::chrono::milliseconds(time));
            continue;
        }
    }
}